package com.mhr.ai.cr.toolWindow

import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.wm.ToolWindow
import com.intellij.ui.components.*
import com.intellij.ui.OnePixelSplitter
import com.mhr.ai.cr.GitMRBundle
import com.mhr.ai.cr.service.LocalGitService
import com.mhr.ai.cr.service.AICodeReviewService
import com.mhr.ai.cr.model.FileChange
import com.mhr.ai.cr.model.AIReviewResult
import com.mhr.ai.cr.provider.AIProviderFactory
import com.mhr.ai.cr.settings.AISettingsState
import java.awt.BorderLayout
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import java.awt.Insets
import java.util.concurrent.CompletableFuture
import javax.swing.*
import javax.swing.event.ListSelectionEvent
import javax.swing.event.ListSelectionListener

class LocalGitToolWindow(private val project: Project, private val toolWindow: ToolWindow) {

    private val localGitService = LocalGitService(project)
    private val aiReviewService = AICodeReviewService(project)
    private val settings = AISettingsState.getInstance(project)
    private var currentChanges: List<FileChange> = emptyList()
    private var currentSelectedFile: FileChange? = null
    
    // AI提供商选择器
    private val providerComboBox = ComboBox<AIProviderFactory.ProviderType>()
    private val providerStatusLabel = JBLabel()

    fun getContent(): JBPanel<*> {
        val panel = JBPanel<JBPanel<*>>(BorderLayout())

        // 创建顶部控制面板
        val topPanel = createTopPanel()
        panel.add(topPanel, BorderLayout.NORTH)

        // 创建左右分割面板
        val splitter = OnePixelSplitter(false, 0.4f) // false = 水平分割, 0.4f = 左侧占40%
        
        // 左侧面板 - 文件列表
        val leftPanel = createLeftPanel()
        splitter.firstComponent = leftPanel
        
        // 右侧面板 - 文件详情
        val rightPanel = createRightPanel()
        splitter.secondComponent = rightPanel

        panel.add(splitter, BorderLayout.CENTER)

        return panel
    }

    private fun createTopPanel(): JBPanel<*> {
        val topPanel = JBPanel<JBPanel<*>>(GridBagLayout())
        val gbc = GridBagConstraints()

        // 标题
        gbc.gridx = 0
        gbc.gridy = 0
        gbc.gridwidth = 3
        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.insets = Insets(10, 10, 5, 10)
        val titleLabel = JBLabel(GitMRBundle.message("local.git.title"))
        titleLabel.font = titleLabel.font.deriveFont(16f)
        topPanel.add(titleLabel, gbc)

        // 当前分支标签
        gbc.gridy = 1
        gbc.gridwidth = 1
        gbc.insets = Insets(5, 10, 5, 5)
        topPanel.add(JBLabel(GitMRBundle.message("local.git.current.branch")), gbc)

        // 当前分支显示
        gbc.gridx = 1
        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.weightx = 1.0
        gbc.insets = Insets(5, 5, 5, 5)
        val currentBranchField = JBTextField()
        currentBranchField.isEditable = false
        topPanel.add(currentBranchField, gbc)

        // 刷新按钮
        gbc.gridx = 2
        gbc.fill = GridBagConstraints.NONE
        gbc.weightx = 0.0
        gbc.insets = Insets(5, 5, 5, 10)
        val refreshButton = JButton(GitMRBundle.message("local.git.refresh"))
        topPanel.add(refreshButton, gbc)

        // 刷新按钮事件
        refreshButton.addActionListener {
            refreshChanges(refreshButton, currentBranchField)
        }

        // 初始加载
        refreshButton.doClick()

        return topPanel
    }

    private fun createLeftPanel(): JBPanel<*> {
        val leftPanel = JBPanel<JBPanel<*>>(BorderLayout())
        
        // 文件列表标题
        val titleLabel = JBLabel("📁 文件变更列表")
        titleLabel.font = titleLabel.font.deriveFont(14f)
        titleLabel.border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
        leftPanel.add(titleLabel, BorderLayout.NORTH)

        // 文件列表
        val fileListModel = DefaultListModel<FileChange>()
        val fileList = JBList(fileListModel)
        fileList.cellRenderer = FileChangeListCellRenderer()
        fileList.selectionMode = ListSelectionModel.SINGLE_SELECTION

        // 文件选择事件
        fileList.addListSelectionListener(object : ListSelectionListener {
            override fun valueChanged(e: ListSelectionEvent) {
                if (!e.valueIsAdjusting) {
                    val selectedFile = fileList.selectedValue
                    currentSelectedFile = selectedFile
                    updateRightPanel(selectedFile)
                }
            }
        })

        val scrollPane = JBScrollPane(fileList)
        leftPanel.add(scrollPane, BorderLayout.CENTER)

        return leftPanel
    }

    private fun createRightPanel(): JBPanel<*> {
        val rightPanel = JBPanel<JBPanel<*>>(BorderLayout())
        
        // 详情标题
        val titleLabel = JBLabel("📝 文件详情")
        titleLabel.font = titleLabel.font.deriveFont(14f)
        titleLabel.border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
        rightPanel.add(titleLabel, BorderLayout.NORTH)

        // 创建垂直分割面板：上方显示文件差异，下方显示AI审核结果
        val verticalSplitter = OnePixelSplitter(true, 0.6f) // true = 垂直分割, 0.6f = 上方占60%
        
        // 上方面板 - 文件差异
        val diffPanel = JBPanel<JBPanel<*>>(BorderLayout())
        val diffArea = JBTextArea()
        diffArea.isEditable = false
        diffArea.font = java.awt.Font("Monospaced", java.awt.Font.PLAIN, 12)
        diffArea.text = "请选择左侧文件查看详情"
        
        val diffScrollPane = JBScrollPane(diffArea)
        diffScrollPane.verticalScrollBarPolicy = JBScrollPane.VERTICAL_SCROLLBAR_ALWAYS
        diffScrollPane.horizontalScrollBarPolicy = JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
        diffPanel.add(diffScrollPane, BorderLayout.CENTER)
        
        verticalSplitter.firstComponent = diffPanel
        
        // 下方面板 - AI审核结果
        val aiPanel = createAIReviewPanel()
        verticalSplitter.secondComponent = aiPanel

        rightPanel.add(verticalSplitter, BorderLayout.CENTER)

        return rightPanel
    }
    
    private fun createAIReviewPanel(): JBPanel<*> {
        val aiPanel = JBPanel<JBPanel<*>>(BorderLayout())
        
        // AI审核标题和控制面板
        val aiTitlePanel = JBPanel<JBPanel<*>>(BorderLayout())
        val aiTitleLabel = JBLabel("🤖 AI 代码审核")
        aiTitleLabel.font = aiTitleLabel.font.deriveFont(14f)
        aiTitleLabel.border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
        aiTitlePanel.add(aiTitleLabel, BorderLayout.WEST)
        
        // 创建右侧控制面板
        val controlPanel = JBPanel<JBPanel<*>>(GridBagLayout())
        val gbc = GridBagConstraints()
        
        // 提供商选择器
        gbc.gridx = 0
        gbc.gridy = 0
        gbc.insets = Insets(2, 5, 2, 5)
        controlPanel.add(JBLabel("提供商:"), gbc)
        
        gbc.gridx = 1
        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.weightx = 0.3
        initializeProviderComboBox()
        controlPanel.add(providerComboBox, gbc)
        
        // 提供商状态标签
        gbc.gridx = 2
        gbc.weightx = 0.4
        gbc.insets = Insets(2, 10, 2, 5)
        updateProviderStatus()
        controlPanel.add(providerStatusLabel, gbc)
        
        // 审核按钮
        gbc.gridx = 3
        gbc.weightx = 0.0
        gbc.fill = GridBagConstraints.NONE
        gbc.insets = Insets(2, 5, 2, 10)
        val reviewButton = JButton("开始审核")
        controlPanel.add(reviewButton, gbc)
        
        aiTitlePanel.add(controlPanel, BorderLayout.EAST)
        aiPanel.add(aiTitlePanel, BorderLayout.NORTH)
        
        // AI审核结果显示区域
        val aiResultArea = JBTextArea()
        aiResultArea.isEditable = false
        aiResultArea.font = java.awt.Font("Monospaced", java.awt.Font.PLAIN, 11)
        aiResultArea.text = "点击\"开始审核\"按钮，AI将分析当前选中的文件变更"
        aiResultArea.lineWrap = true
        aiResultArea.wrapStyleWord = true
        
        val aiScrollPane = JBScrollPane(aiResultArea)
        aiScrollPane.verticalScrollBarPolicy = JBScrollPane.VERTICAL_SCROLLBAR_ALWAYS
        aiScrollPane.horizontalScrollBarPolicy = JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
        aiPanel.add(aiScrollPane, BorderLayout.CENTER)
        
        // 审核按钮事件
        reviewButton.addActionListener {
            performAIReview(reviewButton, aiResultArea)
        }
        
        return aiPanel
    }
    
    /**
     * 初始化提供商选择器
     */
    private fun initializeProviderComboBox() {
        // 添加所有支持的提供商
        AIProviderFactory.getSupportedProviders().forEach { provider ->
            providerComboBox.addItem(provider)
        }
        
        // 设置当前选中的提供商
        val currentProvider = settings.getCurrentProviderType()
        if (currentProvider != null) {
            providerComboBox.selectedItem = currentProvider
        }
        
        // 添加选择变更监听器
        providerComboBox.addActionListener {
            val selectedProvider = providerComboBox.selectedItem as? AIProviderFactory.ProviderType
            if (selectedProvider != null) {
                // 临时切换提供商（不保存到设置）
                updateProviderStatus()
            }
        }
    }
    
    /**
     * 更新提供商状态显示
     */
    private fun updateProviderStatus() {
        val selectedProvider = providerComboBox.selectedItem as? AIProviderFactory.ProviderType
        if (selectedProvider == null) {
            providerStatusLabel.text = "❌ 未选择提供商"
            return
        }
        
        val isConfigValid = settings.isProviderConfigValid(selectedProvider)
        val statusText = if (isConfigValid) {
            "✅ 配置正常"
        } else {
            "⚠️ 需要配置"
        }
        
        providerStatusLabel.text = statusText
        providerStatusLabel.toolTipText = when {
            isConfigValid -> "${selectedProvider.displayName} 配置正常，可以使用"
            else -> "${selectedProvider.displayName} 需要在设置中配置API密钥"
        }
    }
    
    /**
     * 获取当前选中的提供商配置
     */
    private fun getCurrentProviderConfig(): Pair<AIProviderFactory.ProviderType, com.mhr.ai.cr.provider.AIProviderConfig>? {
        val selectedProvider = providerComboBox.selectedItem as? AIProviderFactory.ProviderType
            ?: return null
        
        val config = settings.getProviderConfig(selectedProvider)
        return selectedProvider to config
    }

    private fun refreshChanges(refreshButton: JButton, currentBranchField: JBTextField) {
        refreshButton.isEnabled = false
        refreshButton.text = "加载中..."

        // 使用 CompletableFuture 在后台线程执行
        CompletableFuture.supplyAsync {
            try {
                val result = localGitService.analyzeLocalChanges()
                result.getOrThrow()
            } catch (e: Exception) {
                throw e
            }
        }.thenAccept { gitInfo ->
            // 在EDT线程更新UI
            SwingUtilities.invokeLater {
                currentBranchField.text = gitInfo.currentBranch
                currentChanges = gitInfo.changes
                updateFileList()
                refreshButton.isEnabled = true
                refreshButton.text = GitMRBundle.message("local.git.refresh")
            }
        }.exceptionally { e ->
            SwingUtilities.invokeLater {
                currentBranchField.text = "错误"
                currentChanges = emptyList()
                updateFileList()
                refreshButton.isEnabled = true
                refreshButton.text = GitMRBundle.message("local.git.refresh")
            }
            null
        }
    }

    private fun updateFileList() {
        val leftPanel = (toolWindow.contentManager.contents[0].component as JBPanel<*>)
            .getComponent(1) as OnePixelSplitter
        val fileListScrollPane = (leftPanel.firstComponent as JBPanel<*>).getComponent(1) as JBScrollPane
        val fileList = fileListScrollPane.viewport.view as JBList<FileChange>
        val model = fileList.model as DefaultListModel<FileChange>
        
        model.clear()
        currentChanges.forEach { change ->
            model.addElement(change)
        }
    }

    private fun updateRightPanel(selectedFile: FileChange?) {
        val mainPanel = toolWindow.contentManager.contents[0].component as JBPanel<*>
        val splitter = mainPanel.getComponent(1) as OnePixelSplitter
        val rightPanel = splitter.secondComponent as JBPanel<*>
        val verticalSplitter = rightPanel.getComponent(1) as OnePixelSplitter
        val diffPanel = verticalSplitter.firstComponent as JBPanel<*>
        val scrollPane = diffPanel.getComponent(0) as JBScrollPane
        val detailArea = scrollPane.viewport.view as JBTextArea

        if (selectedFile == null) {
            detailArea.text = "请选择左侧文件查看详情"
            return
        }

        val detailText = buildString {
            appendLine("📁 文件路径: ${selectedFile.newPath}")
            appendLine("🔄 变更类型: ${getChangeTypeText(selectedFile.changeType)}")
            if (selectedFile.addedLines > 0 || selectedFile.removedLines > 0) {
                appendLine("📊 变更统计: +${selectedFile.addedLines} -${selectedFile.removedLines}")
            }
            appendLine()
            appendLine("📝 差异内容:")
            appendLine("═".repeat(60))
            appendLine(selectedFile.diff)
            appendLine("═".repeat(60))
        }

        detailArea.text = detailText
        detailArea.caretPosition = 0 // 滚动到顶部
        
        // 清空AI审核结果
        clearAIReviewResult()
    }
    
    private fun clearAIReviewResult() {
        try {
            val mainPanel = toolWindow.contentManager.contents[0].component as JBPanel<*>
            val splitter = mainPanel.getComponent(1) as OnePixelSplitter
            val rightPanel = splitter.secondComponent as JBPanel<*>
            val verticalSplitter = rightPanel.getComponent(1) as OnePixelSplitter
            val aiPanel = verticalSplitter.secondComponent as JBPanel<*>
            val aiScrollPane = aiPanel.getComponent(1) as JBScrollPane
            val aiResultArea = aiScrollPane.viewport.view as JBTextArea
            
            aiResultArea.text = "点击\"开始审核\"按钮，AI将分析当前选中的文件变更"
        } catch (e: Exception) {
            // 忽略UI组件访问错误
        }
    }
    
    private fun performAIReview(reviewButton: JButton, aiResultArea: JBTextArea) {
        val selectedFile = currentSelectedFile
        if (selectedFile == null) {
            aiResultArea.text = "❌ 请先选择要审核的文件"
            return
        }
        
        // 检查当前选中的提供商配置
        val providerConfig = getCurrentProviderConfig()
        if (providerConfig == null) {
            aiResultArea.text = "❌ 请选择AI提供商"
            return
        }
        
        val (selectedProvider, config) = providerConfig
        val provider = AIProviderFactory.getProvider(selectedProvider)
        if (provider == null) {
            aiResultArea.text = "❌ 未找到提供商: ${selectedProvider.displayName}"
            return
        }
        
        if (!provider.isConfigValid(config)) {
            aiResultArea.text = "❌ ${selectedProvider.displayName} 配置无效，请在设置中配置API密钥"
            return
        }
        
        reviewButton.isEnabled = false
        reviewButton.text = "审核中..."
        aiResultArea.text = "🔄 使用 ${selectedProvider.displayName} 分析代码变更，请稍候..."
        
        // 使用 CompletableFuture 在后台线程执行AI审核
        CompletableFuture.supplyAsync {
            try {
                // 使用选中的提供商进行审核
                val prompt = buildReviewPrompt(selectedFile.diff, selectedFile.newPath)
                val response = provider.reviewCode(prompt, config)
                parseAIResponse(response)
            } catch (e: Exception) {
                AIReviewResult(
                    overallScore = 0,
                    issues = listOf("${selectedProvider.displayName} 服务调用失败: ${e.message}"),
                    suggestions = emptyList(),
                    summary = "审核失败，请检查网络连接和API配置"
                )
            }
        }.thenAccept { result ->
            // 在EDT线程更新UI
            SwingUtilities.invokeLater {
                displayAIReviewResult(result, aiResultArea, selectedProvider.displayName)
                reviewButton.isEnabled = true
                reviewButton.text = "开始审核"
            }
        }.exceptionally { e ->
            SwingUtilities.invokeLater {
                aiResultArea.text = "❌ ${selectedProvider.displayName} 审核失败: ${e.message}"
                reviewButton.isEnabled = true
                reviewButton.text = "开始审核"
            }
            null
        }
    }
    
    private fun displayAIReviewResult(result: AIReviewResult, aiResultArea: JBTextArea, providerName: String = "AI") {
        val resultText = buildString {
            appendLine("🤖 $providerName 代码审核结果")
            appendLine("═".repeat(50))
            appendLine()
            
            appendLine("📊 总体评分: ${result.overallScore}/10")
            appendLine()
            
            if (result.issues.isNotEmpty()) {
                appendLine("⚠️ 发现的问题:")
                result.issues.forEachIndexed { index, issue ->
                    appendLine("${index + 1}. $issue")
                }
                appendLine()
            }
            
            if (result.suggestions.isNotEmpty()) {
                appendLine("💡 改进建议:")
                result.suggestions.forEachIndexed { index, suggestion ->
                    appendLine("${index + 1}. $suggestion")
                }
                appendLine()
            }
            
            appendLine("📝 总结:")
            appendLine(result.summary)
            appendLine()
            appendLine("═".repeat(50))
            appendLine("审核提供商: $providerName")
        }
        
        aiResultArea.text = resultText
        aiResultArea.caretPosition = 0 // 滚动到顶部
    }
    
    /**
     * 构建审核提示词
     */
    private fun buildReviewPrompt(diffContent: String, filePath: String): String {
        val reviewLevelText = when (settings.reviewLevel) {
            "basic" -> "进行基础的代码审核，重点关注明显的问题"
            "strict" -> "进行严格的代码审核，详细分析所有潜在问题"
            else -> "进行标准的代码审核，平衡详细程度和实用性"
        }
        
        return """
请作为一个资深的代码审核专家，对以下代码变更进行详细审核。

审核要求：$reviewLevelText

文件路径: $filePath

代码变更内容:
```
$diffContent
```

请从以下几个方面进行审核：
1. 代码质量和规范性
2. 潜在的bug和安全问题  
3. 性能优化建议
4. 可维护性和可读性
5. 最佳实践建议

请以JSON格式返回审核结果，包含以下字段：
- overallScore: 总体评分(1-10分)
- issues: 发现的问题列表(如果没有问题则为空数组)
- suggestions: 改进建议列表(如果没有建议则为空数组)
- summary: 总结性评价

示例格式：
{
  "overallScore": 8,
  "issues": ["问题1", "问题2"],
  "suggestions": ["建议1", "建议2"],
  "summary": "总体评价"
}

请确保返回有效的JSON格式，不要包含其他文本。
        """.trimIndent()
    }
    
    /**
     * 解析AI响应
     */
    private fun parseAIResponse(aiResponse: String): AIReviewResult {
        return try {
            // 尝试从响应中提取JSON部分
            val jsonStart = aiResponse.indexOf("{")
            val jsonEnd = aiResponse.lastIndexOf("}") + 1
            
            if (jsonStart >= 0 && jsonEnd > jsonStart) {
                val jsonContent = aiResponse.substring(jsonStart, jsonEnd)
                val gson = com.google.gson.Gson()
                val responseMap = gson.fromJson(jsonContent, Map::class.java)
                
                AIReviewResult(
                    overallScore = (responseMap["overallScore"] as? Double)?.toInt() ?: 5,
                    issues = (responseMap["issues"] as? List<*>)?.map { it.toString() } ?: emptyList(),
                    suggestions = (responseMap["suggestions"] as? List<*>)?.map { it.toString() } ?: emptyList(),
                    summary = responseMap["summary"]?.toString() ?: "AI审核完成"
                )
            } else {
                // 如果无法解析JSON，返回原始响应作为总结
                AIReviewResult(
                    overallScore = 7,
                    issues = emptyList(),
                    suggestions = emptyList(),
                    summary = aiResponse
                )
            }
        } catch (e: Exception) {
            AIReviewResult(
                overallScore = 5,
                issues = listOf("解析AI响应失败: ${e.message}"),
                suggestions = emptyList(),
                summary = "AI响应: $aiResponse"
            )
        }
    }

    // 自定义文件列表渲染器
    private inner class FileChangeListCellRenderer : DefaultListCellRenderer() {
        override fun getListCellRendererComponent(
            list: JList<*>?, value: Any?, index: Int, isSelected: Boolean, cellHasFocus: Boolean
        ): java.awt.Component {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)
            
            if (value is FileChange) {
                val fileName = value.newPath.substringAfterLast('/')
                val changeIcon = when (value.changeType) {
                    com.mhr.ai.cr.model.ChangeType.ADDED -> "✅"
                    com.mhr.ai.cr.model.ChangeType.MODIFIED -> "✏️"
                    com.mhr.ai.cr.model.ChangeType.DELETED -> "❌"
                    com.mhr.ai.cr.model.ChangeType.RENAMED -> "🔄"
                }
                
                text = "$changeIcon $fileName"
                toolTipText = "${getChangeTypeText(value.changeType)}: ${value.newPath}"
            }
            
            return this
        }
    }

    private fun getChangeTypeText(changeType: com.mhr.ai.cr.model.ChangeType): String {
        return when (changeType) {
            com.mhr.ai.cr.model.ChangeType.ADDED -> "✅ 新增文件"
            com.mhr.ai.cr.model.ChangeType.MODIFIED -> "✏️ 修改文件"
            com.mhr.ai.cr.model.ChangeType.DELETED -> "❌ 删除文件"
            com.mhr.ai.cr.model.ChangeType.RENAMED -> "🔄 重命名文件"
        }
    }
}